package com.dongzili.config;

import lombok.Getter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;

import javax.validation.constraints.NotEmpty;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

@Component
public class SatokenPredicateFactory extends AbstractRoutePredicateFactory<SatokenPredicateFactory.Config> {

//    @Value("${spring.cloud.gateway.routes}")
//    private RouteDefinition[] routes;

    @Autowired
    GatewayProperties gatewayProperties;

    public SatokenPredicateFactory() {
        super(Config.class);
    }

    public List<String> shortcutFieldOrder() {
        return Arrays.asList("header", "regexp");
    }

    public Predicate<ServerWebExchange> apply(final Config config) {
        final boolean hasRegex = !ObjectUtils.isEmpty(config.remainder);
        return new GatewayPredicate() {
            public boolean test(ServerWebExchange exchange) {
                String satoken = exchange.getRequest().getHeaders().getFirst(config.header);
                if (!StringUtils.hasText(satoken)){
                    return true;
                }
                if(hasRegex){
                    int count = gatewayProperties.getRoutes().size();
                    int lastCharAscii = satoken.charAt(satoken.length() - 1);

                    System.out.println("satoken最后一个字符的ascii码: " + lastCharAscii + " ");
                    System.out.println("remainder=" + config.remainder +", 服务数量:"+count+", lastCharAscii%length = "+ lastCharAscii % count+" ");
                    return lastCharAscii % count == config.remainder;
                }
                return true;
            }

            public Object getConfig() {
                return config;
            }

            public String toString() {
                return String.format("Header: %s regexp=%s", config.header, config.remainder);
            }
        };
    }

    @Getter
    @Validated
    public static class Config {
        private @NotEmpty String header;
//        private String regexp;
        private Integer remainder;
        public Config() {
        }

        public Config setHeader(String header) {
            this.header = header;
            return this;
        }

        public Config setRemainder(Integer remainder) {
            this.remainder = remainder;
            return this;
        }
    }

}
